package com.xioz.android;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector3;

/**
 * WordGameScreen Class
 * used for the generic word game.
 * Note: has no implementation for winning
 * 
 * @author Zong Xiong
 */
public class WordGameScreen implements Screen {

	
/***************************************************
 * Fields
 ***************************************************/
	
	// camera to viewing
	private OrthographicCamera camera;
	// pointer stores where screen was touched
	private Vector3 pointer;
	// batch where drawing is done
	private SpriteBatch batch;
	// stores parent game
	private Game game;
	
	// textures in a word game
	private Texture gameAtlas;
	private TextureRegion background, textBar, popTexture, moreTileTexture, winBoxTexture;
	// buttons that can be pressed in a word game
	private GameObject popButton, moreTileButton;
	// fonts used in a word game
	private BitmapFont bigfont;
	private TextureRegion tileTexture;
	private BitmapFont smallfont;
	// tracks if game is finished or not
	private boolean gameOver = false;
	
	// tracks if player is entering a name for a score
	private boolean enterScore = false;	// tiles used to write score names
	private Tile scoreNameLetters[];
	// texture used as background for name entering for high score
	private TextureRegion scoreEnterTexture;
	// holds inputed name for high score
	private String scoreName = "";
	// buttons used for name input for high score
	private GameObject scoreNameDone, scoreNameDel;

/***************************************************
 * Protected Fields
 ***************************************************/

	// tracks points score by player
	protected int pointScore = 0;
	// tracks tiles destroyed by player
	protected int tilesScore  = 0;
	// tracks play time
	protected GameTimer gameTimer;
	// tracks if board hasn't been over-filled
	protected boolean notFull = true;
	// board being played on
	protected Board gameBoard;
	
/***************************************************
 * Public Methods
 ***************************************************/
	
	/**
	 * Default Constructor
	 * creates a word game with no parent game
	 */
	WordGameScreen() {
		game = null;
		initializeWordGame();
		initializeScoreName();
	}
	
	/**
	 * Constructor with parent game
	 * creates a word game with inputed parent game
	 * 
	 * @param in_game, inputed parent game
	 */
	WordGameScreen(Game in_game) {
		game = in_game;
		initializeWordGame();
		initializeScoreName();
	}

	/** {@inheritDoc} */
	@Override
	public void render(float delta) {
		draw();
		update();
	}

	/** {@inheritDoc} */
	@Override
	public void resize(int width, int height) {
        camera = new OrthographicCamera(width, height);
        camera.position.set(width / 2,height / 2,0);
	}

	/** {@inheritDoc} */
	@Override
	public void show() {
		resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
		render(Gdx.graphics.getDeltaTime());
		gameTimer.setRunning(true);
	}

	/** {@inheritDoc} */
	@Override
	public void hide() {
		gameTimer.setRunning(false);
		
	}

	/** {@inheritDoc} */
	@Override
	public void pause() {
		gameTimer.setRunning(false);
		
	}

	/** {@inheritDoc} */
	@Override
	public void resume() {
		gameTimer.setRunning(true);
		
	}

	/** {@inheritDoc} */
	@Override
	public void dispose() {
		// TODO Auto-generated method stub
		
	}
	/**
	 * setGame
	 * sets the parent game
	 * 
	 * @param newGame, new parent game
	 */
	public void setGame(Game newGame) {
		game = newGame;
	}
	
	
/***************************************************
 * Private Methods
 ***************************************************/

	/**
	 * initializeWordGame
	 * initialization for a word game
	 */
	private void initializeWordGame() {
		// creates board, batch, and vector
		gameBoard = new Board(13,96,294,378);
		batch = new SpriteBatch();
		pointer = new Vector3();
		
		// loads textures and font
		gameAtlas = new Texture("data/backgrounds/gameatlas.png");
		background = new TextureRegion(gameAtlas, 0, 32, 320, 480);
		textBar = new TextureRegion(gameAtlas, 142, 0, 244, 28);
		moreTileTexture = new TextureRegion(gameAtlas, 0, 0, 115, 29);
		popTexture = new TextureRegion(gameAtlas, 389, 0, 46, 29);
		tileTexture = new TextureRegion(gameAtlas, 468, 0, 44, 44);
		winBoxTexture = new TextureRegion(gameAtlas, 320, 44, 192, 100);
		scoreEnterTexture = new TextureRegion(gameAtlas, 320, 204, 192, 96);
		bigfont = new BitmapFont(Gdx.files.internal("data/fonts/comic30.fnt"), false);
		smallfont = new BitmapFont(Gdx.files.internal("data/fonts/comic25.fnt"), false);
		
		// creates buttons and timer
		moreTileButton = new GameObject(185, 13, 115, 29);
		popButton = new GameObject(260, 13, 46, 29);
		gameTimer = new GameTimer();
	}
	
	/**
	 * initializeScoreName
	 * initialization for score name input for new high score
	 */
	private void initializeScoreName() {
		// creates tiles for each letter
		scoreNameLetters = new Tile[26];
		// counter to track current ASCII character, 65 = A and 90 = Z
		int ASCIIcounter = 65;
		for (int i = 0; i < 6; i++) {
			for (int j = 0; j < 5 && ASCIIcounter < 91; j++) {
				scoreNameLetters[i * 5 + j] = new Tile(30 + 55*j, 300 - 40 * i, 30, 30, (char) ASCIIcounter);
				ASCIIcounter++;
			}
		}
		// creates buttons for the score name input
		scoreNameDone = new GameObject( 195, 100, 73, 30 );
		scoreNameDel = new GameObject(110, 100, 60, 30);
	}
/***************************************************
 * Protected Methods
 ***************************************************/
	protected void update() {
		gameTimer.updateTimer();
		if (Gdx.input.justTouched()) {
			camera.unproject(pointer.set(Gdx.input.getX(), Gdx.input.getY(), 0));

			if (gameOver && enterScore) {
				if (scoreNameDone.contains(pointer)) {
					enterScore = false;
				}
				else if (scoreNameDel.contains(pointer) && scoreName.length() > 0) {
					scoreName = scoreName.substring(0, scoreName.length() - 1);
				}
				boolean foundTile = false;
				for (int i=0; i<26 && !foundTile && scoreName.length() < 3; i++) {
					if (scoreNameLetters[i].contains(pointer)) {
						foundTile = true;
						scoreName = scoreName + scoreNameLetters[i].getChar();
					}
				}
			}
			if (gameOver && !enterScore ) {
				game.setScreen(new MenuScreen(game));
			}
			if (gameBoard.contains(pointer)) {
				gameBoard.touchTileAt(pointer);
			}
			else if (popButton.contains(pointer) && gameBoard.hasWord()) {
				int numTiles = gameBoard.getWord().length();
				int newScore = gameBoard.pop_word() + pointScore;
				if (newScore > pointScore) {
					tilesScore += numTiles;
				}
				pointScore = newScore;
			}
			else if (moreTileButton.contains(pointer)&& !gameBoard.hasWord()) {
				notFull  = gameBoard.addTiles(3);
			}
		}
	}

	protected void draw() {
		camera.update();
		batch.setProjectionMatrix(camera.combined);
		batch.begin();
		batch.draw(background, 0, 0);
		if (gameBoard.hasWord()) {
			batch.draw(textBar, 14, 14);
			batch.draw(popTexture, popButton.getX(), popButton.getY());
			smallfont.setColor(Color.BLACK);
			smallfont.draw(batch, gameBoard.getWord(), 15, 39);
		}
		else {
			batch.draw(moreTileTexture, moreTileButton.getX(), moreTileButton.getY());
		}
		for (int i = 0; i < 63; i++) {
			Tile currentTile = gameBoard.getTile(i);
			if (!currentTile.isSelected()) {
				bigfont.setColor(Color.WHITE);
			}
			else {
				bigfont.setColor(Color.BLACK);
			}
			if (currentTile.isVisible()) {
				batch.draw(tileTexture, currentTile.getX(), currentTile.getY());
				bigfont.draw(batch, currentTile.getChar(), currentTile.getX() + 7, currentTile.getY() + 37);
			}
		}
		batch.end();
	}

	protected void printBoard(String text, float x, float y) {
		batch.begin();
		smallfont.setColor(Color.BLACK);
		smallfont.draw(batch, text, x, y);
		batch.end();
	}
	protected void winGame() {
		gameOver  = true;
		gameTimer.setRunning(false);
		batch.begin();
		batch.draw(winBoxTexture, 64, 190);
		bigfont.draw(batch," YOU WIN!",70, 280); 
		batch.end();
	}
	
	protected void loseGame() {
		gameTimer.setRunning(false);
		gameOver  = true;
		gameTimer.setRunning(false);
		batch.begin();
		batch.draw(winBoxTexture, 64, 190);
		bigfont.draw(batch," Game Over",70, 280); 
		batch.end();
	}

	protected void addTiles(int i) {
		notFull = gameBoard.addTiles(i);
	}
	
	protected void enterHighScore() {
		enterScore  = true;
		batch.begin();
		batch.draw(scoreEnterTexture, 10, 10, 300, 460);
		batch.draw(textBar, 30, 390, 260, 30);
		bigfont.setColor(Color.BLACK);
		bigfont.draw(batch, scoreName, 125, 420);
		bigfont.setColor(Color.BLUE);
		bigfont.draw(batch, "NEW HIGH SCORE", 25, 460);
		bigfont.setColor(Color.WHITE);
		bigfont.draw(batch, "A    B    C    D    E", 30, 330);
		bigfont.draw(batch, "F    G    H    I    J", 30, 290);
		bigfont.draw(batch, "K    L    M    N    O", 30, 250);
		bigfont.draw(batch, "P    Q    R    S    T", 30, 210);
		bigfont.draw(batch, "U    V   W    X    Y", 30, 170);
		bigfont.draw(batch, "Z       Del     Done", 30, 130);
		batch.end();
	}
	
	protected String getScoreName() {
		return scoreName;
	}
}
